package com.smforj.ssm.mina.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

/***
 * 单例类
 * 该类实现连接服务器，每次发送消息后并获取返回信息
 *
 * @author Haijun Gao 
 * @date 2016-8-4 上午9:16:57
 * @desp http://www.cnblogs.com/saga5998/
 * @email 573107773@qq.com
 */
public class SocketClient {

    private static SocketClient instance = null;
    private static Socket socket = null;
    private static SocketAddress endpoint = null;
    private static int timeout = 10000;

    private String charset = "UTF-8";


    private SocketClient() {
    }

    /***
     * 创建连接
     * @param ip 连接的ip
     * @param port 连接的端口
     * @return 连接的对象
     * @date 2016-8-6 上午11:40:59
     */
    public static SocketClient connect(String ip, int port) {
        System.out.println("connect " + ip + "  " + port);
        return init(ip, port);
    }

    private void connect() {
        if (instance != null && socket != null && endpoint != null) {
            //与服务端建立连接
            try {
                socket.connect(endpoint, timeout);
                System.out.println("connect...");
            } catch (UnknownHostException e) {
                e.printStackTrace();
                socket = null;
            } catch (IOException e) {
                e.printStackTrace();
                socket = null;
            }
        }
    }

    /***
     * 创建对象
     * @param host 连接的ip
     * @param port 连接的端口
     * @return SocketClient
     * @date 2016-8-6 上午11:42:12
     */
    private static SocketClient init(String host, int port) {
        if (instance == null) {
            //与服务端建立连接
            try {
                //socket = new Socket(host,port);
                socket = new Socket();
                endpoint = new InetSocketAddress(host, port);
                socket.connect(endpoint, timeout);
                System.out.println("connect...");
            } catch (UnknownHostException e) {
                e.printStackTrace();
                socket = null;
            } catch (IOException e) {
                e.printStackTrace();
                socket = null;
            }
            instance = new SocketClient();
        }
        return instance;
    }


    /***
     * 每次读取一行以换行符为结束点 该方法会关闭socket
     * @param sendMsg  发送的消息
     * @return 接受到的消息
     * @date 2016-8-4 上午9:14:12
     */
    public String sendAndRead(String sendMsg) {
        System.out.println("send" + sendMsg);
        String rMsg = "";
        if (socket == null)
            return rMsg;
        if (socket != null && !socket.isConnected())
            connect();
        if (socket != null && socket.isConnected()) {
            try {
                //由Socket对象得到输出流，并构造PrintWriter对象
                BufferedWriter os = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), getCharset()));
                String readline = sendMsg; //从系统标准输入读入一字符串
                //将从系统标准输入读入的字符串输出到Server
                os.write(readline);
                //刷新输出流，使Server马上收到该字符串
                os.flush();
                //由Socket对象得到输入流，并构造相应的BufferedReader对象
                BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream(), getCharset()));
                //最多等待10秒读取时间
                socket.setSoTimeout(getTimeout());
                //读取消息
                rMsg = is.readLine();
//                rMsg = rMsg.substring(27);
//                os.close(); //关闭Socket输出流
//                is.close(); //关闭Socket输入流
//                os = null;
//                is = null;
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
                rMsg = "";
            } finally {
//                try {
//                    socket.close();
//                } catch (Exception ex) {
//                    System.out.println(ex.getMessage());
//                }
            }
        }
        System.out.println("response" + rMsg);
        return rMsg;
    }

/*	public String sendAndRead(String msg){
        System.out.println("send"+msg);
		String rMsg = "";
		if(socket != null && socket.isConnected())
		{
			try{  
				OutputStream out = socket.getOutputStream();  
				InputStream sin = socket.getInputStream();  
				
				//将从系统标准输入读入的字符串输出到Server 
				byte buf [] = new byte[512];  
			    buf = msg.getBytes();  
			    out.write(buf);   
		        System.out.println("send ok ---> " + sin + "     Out: " + out);  
		        out.flush();
		        
		        
		        StringBuffer sb = new StringBuffer();
		        byte ibuf[] = new byte[512];   
		        int len; 
		        while((len = sin.read(ibuf,0,ibuf.length)) != -1)
		        {
		        	sb.append(new String(ibuf, 0, len-1)); 
		        	len = sin.read(ibuf,0,ibuf.length); 
		        } 
		        out.close();
		        sin.close();
		        rMsg = sb.toString();
			}catch(Exception ex)
			{
				System.out.println(ex.getMessage()); 
				rMsg = "";
			} 
		}
		return rMsg;
	} */

    /***
     * 关闭连接 并销毁对象
     *
     * @return
     * @date 2016-8-6 上午11:43:33
     */
    public boolean close() {
        System.out.println("close");
        try {
            socket.close();
            socket = null;
            instance = null;
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            socket = null;
            instance = null;
            return false;
        }
    }

    public static void main(String[] args) throws IOException {
        //为了简单起见，所有的异常都直接往外抛
        String host = "192.168.1.101";  //要连接的服务端IP地址
        int port = 6789;   //要连接的服务端对应的监听端口   
        SocketClient sc = SocketClient.connect(host, port);
        sc.setCharset("UTF-8");
        String str = sc.sendAndRead("11");
        System.out.println("我返回的信息是：" + str);

    }

    public String getCharset() {
        return charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public int getTimeout() {
        return SocketClient.timeout;
    }

    public void setTimeout(int timeout) {
        SocketClient.timeout = timeout;
    }

}
